﻿using System.Collections.Generic;
using System.Linq;
using Microsoft.FxCop.Sdk;

namespace LINQtoFxCop.Core
{
  public class ApplicationNode : Node
  {
    private readonly ICollection<AssemblyNode> _assemblies;
    private readonly NamespaceCollection _namespaces;
    private readonly ICollection<TypeNode> _types;
    private readonly ICollection<Member> _members;

    internal ApplicationNode(IEnumerable<ModuleNode> modules)
      : base(NodeType.Undefined)
    {
      _assemblies = new HashSet<AssemblyNode>();
      _namespaces = new NamespaceCollection();
      _types = new HashSet<TypeNode>();
      _members = new HashSet<Member>();

      Build(modules);
    }

    private void Build(IEnumerable<ModuleNode> modules)
    {
      modules.ForEach(module => _assemblies.Add(new AssemblyNode(module)));

      //split modules into types, members etc for easier querying.
      //The division is based on the division made by NDepend
      foreach (var assembly in _assemblies)
      {
        _namespaces.Add(assembly.Types);
        _types.Add(assembly.Types);
        assembly.Types.ForEach(type => type.Members.ForEach(member => _members.Add(member)));
      }
      Fields = _members.OfType<Field>();
    }

    public IEnumerable<TypeNode> Types
    { get { return _types; } }
    public IEnumerable<Member> Members
    { get { return _members; } }
    public IEnumerable<Namespace> Namespaces
    { get { return _namespaces; } }
    public IEnumerable<AssemblyNode> Assemblies
    { get { return _assemblies; } }
    public IEnumerable<Field> Fields
    { get; private set; }
  }
}
